feat(ci): add contributor reputation check workflow#1520
feat(ci): add contributor reputation check workflow#1520aaronpowell merged 1 commit intogithub:stagedfrom
Conversation
There was a problem hiding this comment.
main, but PRs should target staged.
The main branch is auto-published from staged and should not receive direct PRs.
Please close this PR and re-open it against the staged branch.
You can change the base branch using the Edit button at the top of this PR,
or run: gh pr edit 1520 --base staged
There was a problem hiding this comment.
Pull request overview
Adds a new GitHub Actions workflow to automatically screen new PR/issue authors using the Agent Governance Toolkit (AGT) and to surface elevated-risk contributors via comments and labels.
Changes:
- Introduces
.github/workflows/contributor-check.ymltriggered onpull_request_targetandissuesopened events. - Runs two AGT Python checks (profile + credential audit) and computes an overall risk level.
- Posts a PR/issue comment and applies a
needs-review:<RISK>label for MEDIUM/HIGH outcomes.
|
Please don't contribute new workflows and policies without discussing with the maintainers first. |
| pull_request_target: | ||
| types: [opened] | ||
| issues: | ||
| types: [opened] |
There was a problem hiding this comment.
Have you experimented with running this on discussions too? Would that be useful to do?
| - name: Checkout AGT scripts | ||
| uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2 | ||
| with: | ||
| repository: microsoft/agent-governance-toolkit | ||
| sparse-checkout: scripts | ||
| path: agt |
There was a problem hiding this comment.
Do we have to clone the repo? Is it not possible to install the CLI with pip?
If we have to clone the repo, it might be a good idea to pin a tag or release, so that if there is drift in the script it doesn't result in this action failing.
| profile="${{ steps.profile.outputs.risk }}" | ||
| cred="${{ steps.credential.outputs.risk }}" | ||
|
|
||
| if [ "$risk" = "HIGH" ]; then icon="🔴"; else icon="🟡"; fi |
There was a problem hiding this comment.
Should low risk not have a separate icon?
| body="<!-- agt-contributor-check --> | ||
| $icon **Contributor Reputation Check: $risk risk** | ||
|
|
||
| | Check | Risk | |
There was a problem hiding this comment.
Ah, my comment on the discussion is probably irrelevant - I wrote that before reviewing the PR and I was assuming the PR was going to be using the action and Python script the action runs from the repo, not a custom script here.
| --repo "${{ github.repository }}" \ | ||
| --json > /tmp/cred.json 2>/tmp/cred.log | ||
| set -e | ||
| risk=$(python -c "import json; print(json.load(open('/tmp/cred.json'))['risk'])" 2>/dev/null || echo "UNKNOWN") |
There was a problem hiding this comment.
It only extracts the risk property from the JSON, is there anything else from the JSON that might be useful to extract and display?
| --repo "${{ github.repository }}" \ | ||
| --json > /tmp/cred.json 2>/tmp/cred.log | ||
| set -e | ||
| risk=$(python -c "import json; print(json.load(open('/tmp/cred.json'))['risk'])" 2>/dev/null || echo "UNKNOWN") |
There was a problem hiding this comment.
| risk=$(python -c "import json; print(json.load(open('/tmp/cred.json'))['risk'])" 2>/dev/null || echo "UNKNOWN") | |
| risk=$(cat '/tmp/cred.json' | jq '.risk // "UNKNOWN"') |
Can simplify with jq rather than loading a Python environment for that.
| --username "${{ steps.author.outputs.username }}" \ | ||
| --json > /tmp/profile.json 2>/tmp/profile.log | ||
| set -e | ||
| risk=$(python -c "import json; print(json.load(open('/tmp/profile.json'))['risk'])" 2>/dev/null || echo "UNKNOWN") |
There was a problem hiding this comment.
| risk=$(python -c "import json; print(json.load(open('/tmp/profile.json'))['risk'])" 2>/dev/null || echo "UNKNOWN") | |
| risk=$(cat '/tmp/profile.json' | jq '.risk // "UNKNOWN"') |
Can simplify with jq rather than loading a Python environment for that.
| --username "${{ steps.author.outputs.username }}" \ | ||
| --json > /tmp/profile.json 2>/tmp/profile.log | ||
| set -e | ||
| risk=$(python -c "import json; print(json.load(open('/tmp/profile.json'))['risk'])" 2>/dev/null || echo "UNKNOWN") |
There was a problem hiding this comment.
It only extracts the risk property from the JSON, is there anything else from the JSON that might be useful to extract and display?
f6ee187 to
44bd367
Compare
…ommands (#1711) Add agt-contributor-check and agt-credential-audit as console_scripts entry points in the agent-governance-toolkit package. This allows consumers to pip install instead of cloning the repo to access these tools. Addresses: github/awesome-copilot#1520 review feedback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
|
Addressed all review feedback in d49d70f: pip install instead of cloning - Replaced repo checkout with \pip install agent-governance-toolkit==3.3.0. CLI entry points (\�gt-contributor-check, \�gt-credential-audit) just landed on AGT main (microsoft/agent-governance-toolkit#1711). This pins to a release version and eliminates the supply-chain concern. jq instead of Python - Switched to \jq -r '.risk // "UNKNOWN"'. Simpler, no Python env needed for JSON parsing. UNKNOWN maps to MEDIUM - Fixed. The workflow now fails closed: unknown/error states are treated as MEDIUM risk, not LOW. Markdown indentation - Switched to heredoc so the comment renders correctly. Unused variable - Removed. Low risk icon - Added ✅ for LOW in the job summary. More JSON data - Intentionally keeping only the risk level in the PR comment. The verbose output is by design: we surface the signal (risk level) and link to the workflow run for anyone who wants the full breakdown. This avoids leaking profile heuristic details that could help adversaries tune their patterns. Discussions trigger - Good idea, will explore as a follow-up once we validate this on PRs/issues first. @aaronpowell ready for re-review when you get a chance. |
|
I've changed the base branch of the PR, but because you branched from You can attempt to fix this with a rebase: If that does not resolve it, you can run |
Add automated contributor reputation screening on PR/issue open events using AGT's pip-installable CLI tools. Detects coordinated inauthentic contribution patterns (credential laundering, spray-and-pray). - Installs via pip (pinned to agent-governance-toolkit==3.3.0) - Uses jq for JSON parsing - Fails closed: UNKNOWN risk maps to MEDIUM - Posts risk summary comment on MEDIUM/HIGH with link to workflow run - Adds needs-review label for maintainer attention Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
d49d70f to
e5f900e
Compare
|
Rebased onto \staged. PR is now a single clean commit with just the workflow file (1 file, +152 lines). Thanks for fixing the base branch. |
…ommands (microsoft#1711) Add agt-contributor-check and agt-credential-audit as console_scripts entry points in the agent-governance-toolkit package. This allows consumers to pip install instead of cloning the repo to access these tools. Addresses: github/awesome-copilot#1520 review feedback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Summary
Add automated contributor reputation screening on PR/issue open events to detect coordinated inauthentic contribution patterns (e.g., credential-laundering campaigns, spray-and-pray governance issues).
How it works
Why this matters
Multiple AI agent framework repos have been targeted by coordinated campaigns that:
This workflow helps maintainers catch these patterns early.
Dependencies
pull_request_targetandissuesevents onlyGITHUB_TOKENCo-authored-by: Copilot 223556219+Copilot@users.noreply.github.com